package com.xxgg.start.controller.system;


import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxgg.common.annotation.OpenLog;
import com.xxgg.common.enums.BusinessType;
import com.xxgg.common.exception.ApiException;
import com.xxgg.common.exception.Asserts;
import com.xxgg.common.result.ResultJSON;
import com.xxgg.system.model.po.Role;
import com.xxgg.system.model.po.UserRole;
import com.xxgg.system.service.RoleService;
import com.xxgg.system.service.UserRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 先谢郭嘉
 * @since 2023-01-31 04:33:30
 */
@Validated
@Slf4j
@Api(tags = "角色管理")
@RestController
@RequestMapping("/system/role")
public class RoleController {

    @Resource
    RoleService roleService;
    @Resource
    UserRoleService userRoleService;

    @OpenLog(module = "角色管理", name = "获取角色权限码集合", businessType = BusinessType.SELECT)
    @ApiOperation(value = "获取角色权限码集合",httpMethod = "GET")
    @ApiImplicitParam(value = "角色id",name = "roleId",required = true)
    @GetMapping("/permission")
    public ResultJSON<List<String>> getRolePermission(Integer roleId) throws ApiException {
        return ResultJSON.success(roleService.getRolePermission(roleId));
    }

    @SaCheckPermission("role:add")
    @OpenLog(module = "角色管理", name = "新增角色", businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增角色",httpMethod = "POST")
    @ApiImplicitParam(value = "角色实体",name = "role",required = true)
    @PostMapping("/add")
    public ResultJSON<Boolean> addRole(@RequestBody Role role){
        return roleService.save(role) ? ResultJSON.success() : ResultJSON.error();
    }

    @SaCheckPermission("role:update")
    @OpenLog(module = "角色管理", name = "编辑角色", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "编辑角色",httpMethod = "POST")
    @ApiImplicitParam(value = "角色实体",name = "role",required = true)
    @PostMapping("/update")
    public ResultJSON<Boolean> updateRole(@RequestBody Role role) throws ApiException {
        // 根据角色id获取角色信息（版本号）
        Role roleV = roleService.getById(role.getRoleId());
        Asserts.isTrue(roleV == null, "不存在该角色！");

        // 编辑角色（版本号需一致）
        LambdaUpdateWrapper<Role> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Role::getRoleId, role.getRoleId())
                .eq(Role::getVersion, roleV.getVersion());
        role.setVersion(role.getVersion() + 1);
        return roleService.update(role, wrapper) ? ResultJSON.success() : ResultJSON.error();
    }

    @SaCheckPermission("role:delete")
    @OpenLog(module = "角色管理", name = "删除角色（物理删除）", businessType = BusinessType.DELETE)
    @ApiOperation(value = "删除角色（物理删除）",httpMethod = "DELETE")
    @ApiImplicitParam(value = "角色id",name = "roleId",required = true)
    @DeleteMapping("/delete")
    public ResultJSON<Boolean> deleteRole(Integer roleId) throws ApiException {
        // 判断改角色是否与用户有对应关系
        long count = userRoleService.lambdaQuery()
                .eq(UserRole::getRoleId, roleId)
                .count();
        Asserts.isTrue(count > 0, "角色与用户存在对应关系，无法删除该角色！");
        return roleService.removeById(roleId) ? ResultJSON.success() : ResultJSON.error();
    }

    @OpenLog(module = "角色管理", name = "分页查询角色列表", businessType = BusinessType.PAGE)
    @ApiOperation(value = "分页查询角色列表",httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "每页数量",name = "size",required = true),
            @ApiImplicitParam(value = "页码",name = "current",required = true),
            @ApiImplicitParam(value = "模糊查询条件",name = "search",required = false),
    })
    @GetMapping("/page")
    public ResultJSON<Page<Role>> rolePage(Integer size, Integer current, String search) {
        Page<Role> rolePage = roleService.lambdaQuery()
                .and(StrUtil.isNotBlank(search), item -> item
                        .like(Role::getRoleCode, search).or()
                        .like(Role::getRoleName, search).or()
                        .like(Role::getDescription, search))
                .orderByDesc(Role::getUpdateTime)
                .page(new Page<>(current, size));
        return ResultJSON.success(rolePage);
    }

    @SaCheckPermission("role:grant")
    @OpenLog(module = "角色管理", name = "角色授权", businessType = BusinessType.GRANT)
    @ApiOperation(value = "角色授权",httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "角色id",name = "roleId",required = true),
            @ApiImplicitParam(value = "菜单id集合",name = "menuIdList",required = true)
    })
    @GetMapping("/grant")
    public ResultJSON<Boolean> updateRoleGrant(Integer roleId, @RequestParam("menuIdList") List<String> menuIdList) throws ApiException {
        return roleService.updateRoleGrant(roleId, menuIdList) ? ResultJSON.success() : ResultJSON.error();
    }
}
